#pragma once

#include <QObject>
#include "opencv2/opencv.hpp"
#include <iostream>
#include <QPixmap>
#include "../../common/utils/ImageUtils.h"
#include <QDebug>

using namespace std;
using namespace cv;


/**
* 基础像素操作
*/
class BasePixelOption : public QObject
{
	Q_OBJECT

public:
	BasePixelOption(QObject* parent);
	~BasePixelOption();
public:
	/**
	 * 显示原图
	 * @brief showSrcImage
	 * @param filePath 文件路径
	 * @return 返回QLabel
	 */
	virtual QPixmap showSrcImage(const char* filePath);
	/**
	 * 像素取反
	 * @brief pixleReverse
	 */
	virtual list<QPixmap> pixleReverse(const char* filePath);
	/**
	 * 图像融合
	 * @brief imageFuse
	 * @param filePath
	 * @param label
	 */
	virtual void imageFuse(const char* filePath_first, const char* filePath_second, float mAlpha, Mat* mats);
	/**
	 * 调整图像亮度及对比度
	 * 亮度：0~255的像素值 值越大图像就越亮，值越小图像就越暗
	 *      提升亮度的方法通常可以直接将像素的值调大，降低亮度就将值调小
	 * 对比度：指的是图像中像素点的差异，差异越大对比多越大，差异越小对比多越小。适当的调整对比度可以增加图像的清晰度
	 * @brief increaseBrightness
	 * @param filePath
	 * @param label
	 */
	virtual void increaseBrightnessContrastRatio(const char* filePath, double beta, double alpha, Mat* mats);
	/**
	 * 绘制线、矩形、椭圆、圆、多边形、文本
	 * @brief drawShape
	 * @param label
	 */
	virtual void drawShape(Mat* mats);
	/**
	 * 均值模糊：用于图像的降噪（对椒盐噪声有很好的抑制效果）
	 * @brief showBlur
	 * @param filePath
	 * @param label
	 */
	virtual void showBlur(const char* filePath, int ksize, Mat* mats);

	/**
	 * 高斯模糊：用于图像的降噪，其对自然界的噪声有很好的抑制作用
	 * @brief showGaussianBlue
	 * @param filePath
	 * @param label
	 * @param kSize 高斯核大小
	 */
	virtual void showGaussianBlue(const char* filePath, int kSize, Mat* mats);
	/**
	 * 中值滤波：终止滤波用于图像的降噪，其对椒盐噪声有很好的抑制作用（黑白点）
	 * @brief showMediaBlur
	 * @param filePath
	 * @param label
	 */
	virtual void showMediaBlur(const char* filePath, int kSize, Mat* mats);


	/**
	 * 双边滤波：其可以很好的保留边缘的同时对平坦区域进行降噪
	 * @brief showBilateralFilter
	 * @param filePath
	 * @param g_d 卷积核大小，表示在过滤过程中，每个像素邻域的直径，如果设置为非正数，则从sigmaSpace计算得来
	 * @param g_sigmaColor 颜色空间方差，值越大表明混合的区域越广（就表明该像素邻域内有更宽广的颜色会被混合到一起，产生较大的半相等颜色区域）
	 * @param g_sigmaSpace 坐标空间方差，值越大表明影响的像素越多（值越大，意味着越远的像素会相互影响，从而使更大的区域足够相似的颜色获取相同的颜色。当d>0，d指定了邻域大小且与sigmaSpace无关。否则，d正比于sigmaSpace）
	 */
	virtual void showBilateralFilter(const char* filePath, int g_d, int g_sigmaColor, int g_sigmaSpace, Mat* mats);
	/**
	 * 提起图像中的英文字母
	 * @brief showCleanImage
	 * @param filePath
	 * @param kSize 高斯模糊的卷积核大小 默认值5
	 * @param thresholdMin 需要设置的阈值 默认值160
	 * @param threadholdMax最大值 最大值固定255
	 * @param dilateKSize 膨胀的卷积核大小 ，默认3
	 * @param erodeKsize 腐蚀的卷积核大小，默认7
	 */
	virtual void showCleanImage(const char* filePath, int kSize, int thresholdMin, int thresholdMax, int dilateKSize, int erodeKsize, Mat* mats);
	/**
	 * 形态学开操作
	 * @brief showImageOpen
	 * @param filePath
	 */
	virtual void showImageOpen(const char* filePath, int erodeKSize, int dilateKSize, Mat* mats);
	/**
	 * 形态学闭操作
	 * @brief showImageClose
	 * @param filePath
	 */
	virtual void showImageClose(const char* filePath, int erodeKSize, int dilateKSize, Mat* mats);
	/**
	 * 形态学梯度（基本梯度）：膨胀减去腐蚀
	 * @brief showMorphologicalGradient
	 * @param filePath
	 */
	virtual void showMorphologicalGradient(const char* filePath, int kSize, int mType, Mat* mats);
	/**
	 * 顶帽操作：相当于原图像与开操作之间的差值图像
	 * @brief showTopHat
	 * @param filePath
	 */
	virtual void showTopHat(const char* filePath, int kSize, Mat* mats);

	/**黑帽操作：相当于原图像与闭操作之间的差值图像
	 * @brief showBlackHat
	 * @param filePath
	 */
	virtual void showBlackHat(const char* filePath, int kSize, Mat* mats);

	/**小案例：提取提取项目中的字母或者直线
	 * @brief showLines
	 * @param filePath
	 * @param type 0直线 1字母
	 */
	virtual void showLines(const char* filePath, Mat* mats);
	/**
	 * 上采样:利用拉普拉斯金字塔进行图像重建
	 * @brief showPyrUp
	 * @param filePath
	 */
	virtual void showPyrUp(const char* filePath, int type, int w, Mat* mats);
	/**
	 * 降采样：利用高斯金字塔进行降采样
	 * @brief showPyrDown
	 * @param filePath
	 */
	virtual void showPyrDown(const char* filePath, int w, Mat* mats);
	/**
	 * 高斯不同：把同一张图片再不同的参数下做高斯模糊之后的结果相减，得到的输出图像称为高斯不同
	 * 高斯不同是图像的内在特征，在灰度图像增强、角点检测中经常用到
	 * @brief showGaussianDiff
	 * @param filePath
	 */
	virtual void showGaussianDiff(const char* filePath, int firstKSize, int secondKSize, Mat* mats);

	/**
	 * 使用自定义卷积核filter2D
	 * @brief showCustomKernelFilter2D
	 * @param filePath
	 * @param type:0 Robert横向、1 Robert纵向、2 Sobel横向 、3 Sobel纵向、4 拉普拉斯算子
	 */
	virtual void showCustomKernelFilter2D(const char* filePath, Mat* mats);
	/**
	 * 1.合并rebort的x方向梯度和y方向的梯度
	 * 2.合并sobel的x方向的梯度和y方向的梯度
	 * @brief showCustomKernelFilter2DMergeXY
	 * @param filePath
	 */
	virtual void showCustomKernelFilter2DMergeXY(const char* filePath, Mat* mats);
	/**
	 * 填充图像边缘
	 * @brief showCopyMakeBorder
	 * @param filePath
	 */
	virtual void showCopyMakeBorder(const char* filePath, int borderWidth, Mat* mats);
	/**
	 * 使用Sobel和Scharr计算图形梯度
	 * @brief showSobelAndScharr
	 * @param filePath
	 */
	virtual void showSobelAndScharr(const char* filePath, int gaussKSize, int sobelKSize, Mat* mats);
	/**
	 * 使用拉普拉斯算子显示梯度图像
	 * @brief showLaplacian
	 * @param filePath
	 */
	virtual void showLaplacian(const char* filePath, int gaussKSize, int laplacianKSize, Mat* mats);

	/**
	 * 边缘检测
	 * @brief showCanny
	 * @param filePath
	 * @param threshold_min 第一个阈值，用于在检测到的边缘上消除弱的像素点。通常设置为较小的值，例如50或100
	 * @param threshold_max 第二个阈值，用于确定哪些像素点是强边缘，哪些是弱边缘。通常设置为较大的值，例如150或200
	 * @param sobelKSize Sobel算子的核大小。通常设置为3，表示使用一个3x3的核，但也可以设置为5、7或其他值
	 * @param blurKSize 均值滤波的卷积核大小
	 */
	virtual void showCanny(const char* filePath, int threshold_min, int threshold_max, int blurKSize, int sobelKSize, Mat* mats);
	/**
	 * 检测霍夫直线：
	 * 1.转灰度图像
	 * 2.进行边缘检测
	 * 3.进行hough直线检测
	 * @brief showHoughLine
	 * @param filePath
	 */
	virtual void showHoughLine(const char* filePath, int threshold_min, int threshold_max, int cannySobelKSize,
		int rho, int threshold_p, double minLineLength, double maxLineGap, Mat* mats);
	/**
	 * 检测霍夫圆
	 * 1.均值模糊
	 * 2.边缘检测
	 * 3.霍夫圆检测
	 * @brief showHoughCircles
	 * @param filePath
	 * @param param1  
	 * @param param2
	 */
	virtual void showHoughCircles(const char* filePath, int param1, int param2, int minRadius, int maxRadius, Mat* mats);
	/**
	 * 重复映射
	 * @brief showRemap
	 * @param filePath
	 */
	virtual void showRemap(const char* filePath, Mat* mats);
	/**
	 * 直方图均衡化：可提高图像的对比度
	 * @brief showEqualizeHist
	 * @param filePath
	 */
	virtual void showEqualizeHist(const char* filePath, Mat* mats);

	/**
	 * 直方图均衡化彩色图片
	 * @brief showEqualizeHistColorImage
	 * @param filePath
	 */
	virtual void showEqualizeHistColorImage(const char* filePath, Mat* mats);

	/**
	 * 绘制直方图
	 * @brief drawCalcHist
	 * @param filePath
	 */
	virtual void drawCalcHist(const char* filePath, Mat* mats);
	/**
	 * 直方图反向投影
	 * @brief showCalcHistCompare
	 */
	virtual void showCalcHistBackProject(const char* filePath,Mat* mats);
	/**
	 * 模板匹配
	 * @brief showMatchTemplate
	 * @param filePath
	 */
	virtual void showMatchTemplate(const char* filePath, const char* templateFilePath, Mat* mats);
	/**
	 * 发现轮廓
	 * @brief showFindContours
	 * @param filePath
	 */
	virtual void showFindContours(const char* filePath, Mat* mats);
	/**
	 * 轮廓周围绘制矩形及椭圆
	 * @brief showContoursRectAndCircle
	 * @param filePath
	 */
	virtual void showContoursRectAndCircle(const char* filePath,Mat *mats);
	/**
	 * 分水岭算法简单演示
	 * @brief showWaterShedImage
	 * @param filePath
	 */
	virtual void showWaterShedImage(const char* filePath);
};
